import { Router } from 'express';
import { body, validationResult } from 'express-validator';
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import multer from 'multer';
import path from 'path';
import fs from 'fs';
import { config } from '../config';
import { prisma } from '../lib/prisma';
import { CustomError, AuthenticationError, ConflictError } from '../middleware/errorHandler';

const router = Router();

// 配置文件上传
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    const uploadDir = path.join(__dirname, '../../uploads/avatars');
    // 确保目录存在
    if (!fs.existsSync(uploadDir)) {
      fs.mkdirSync(uploadDir, { recursive: true });
    }
    cb(null, uploadDir);
  },
  filename: (req, file, cb) => {
    // 生成唯一文件名
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    const ext = path.extname(file.originalname);
    cb(null, `avatar-${uniqueSuffix}${ext}`);
  }
});

const upload = multer({
  storage,
  limits: {
    fileSize: 5 * 1024 * 1024, // 5MB
  },
  fileFilter: (req, file, cb) => {
    // 只允许图片文件
    if (file.mimetype.startsWith('image/')) {
      cb(null, true);
    } else {
      cb(new Error('只允许上传图片文件'));
    }
  }
});

// 用户注册
router.post('/register', [
  body('username').isLength({ min: 3, max: 50 }).withMessage('用户名长度必须在3-50个字符之间'),
  body('email').isEmail().withMessage('请输入有效的邮箱地址'),
  body('password').isLength({ min: 6 }).withMessage('密码长度至少6位'),
  body('role').optional().isIn(['ADMIN', 'EDITOR', 'VIEWER']).withMessage('无效的用户角色')
], async (req, res, next) => {
  try {
    // 验证请求参数
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      const errorMessages = errors.array().map(err => `${err.type === 'field' ? err.path : 'unknown'}: ${err.msg}`).join(', ');
      throw new CustomError(`请求参数验证失败: ${errorMessages}`, 400);
    }

    const { username, email, password, role = 'VIEWER' } = req.body;

    // 检查用户是否已存在
    const existingUser = await prisma.user.findFirst({
      where: {
        OR: [{ email }, { username }]
      }
    });

    if (existingUser) {
      throw new ConflictError('用户名或邮箱已存在');
    }

    // 加密密码
    const hashedPassword = await bcrypt.hash(password, 12);

    // 创建用户
    const user = await prisma.user.create({
      data: {
        username,
        email,
        password: hashedPassword,
        role
      },
      select: {
        id: true,
        username: true,
        email: true,
        role: true,
        avatar: true,
        status: true,
        createdAt: true
      }
    });

    // 生成 JWT 令牌
    const token = jwt.sign(
      { userId: user.id, role: user.role },
      config.JWT_SECRET,
      { expiresIn: config.JWT_ACCESS_EXPIRES_IN } as any
    );

    res.status(201).json({
      code: 200,
      message: '用户注册成功',
      data: {
        user,
        token
      }
    });
  } catch (error) {
    next(error);
  }
});

// 用户登录
router.post('/login', [
  body('username').notEmpty().withMessage('用户名不能为空'),
  body('password').notEmpty().withMessage('密码不能为空')
], async (req, res, next) => {
  try {
    // 验证请求参数
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      const errorMessages = errors.array().map(err => `${err.type === 'field' ? err.path : 'unknown'}: ${err.msg}`).join(', ');
      throw new CustomError(`请求参数验证失败: ${errorMessages}`, 400);
    }

    const { username, password } = req.body;

    // 查找用户（支持用户名或邮箱登录）
    const user = await prisma.user.findFirst({
      where: {
        OR: [
          { username },
          { email: username }
        ]
      }
    });

    if (!user) {
      return res.json({
        code: 500,
        message: '账号密码错误',
        data: null
      });
    }

    // 验证密码
    const isValidPassword = await bcrypt.compare(password, user.password);
    if (!isValidPassword) {
      return res.json({
        code: 500,
        message: '账号密码错误',
        data: null
      });
    }

    // 生成 JWT 令牌
    const token = jwt.sign(
      { userId: user.id, role: user.role },
      config.JWT_SECRET,
      { expiresIn: config.JWT_ACCESS_EXPIRES_IN } as any
    );

    // 更新最后登录时间
    await prisma.user.update({
      where: { id: user.id },
      data: { lastLoginAt: new Date() }
    });

    res.json({
      code: 200,
      message: '登录成功',
      data: {
        user: {
          id: user.id,
          username: user.username,
          email: user.email,
          role: user.role,
          avatar: user.avatar
        },
        token
      }
    });
  } catch (error) {
    next(error);
  }
});

// 刷新令牌
router.post('/refresh', async (req, res, next) => {
  try {
    const { token } = req.body;

    if (!token) {
      throw new AuthenticationError('令牌不能为空');
    }

    // 验证令牌
    const decoded = jwt.verify(token, config.JWT_SECRET) as any;
    
    // 查找用户
    const user = await prisma.user.findUnique({
      where: { id: decoded.userId },
      select: {
        id: true,
        username: true,
        email: true,
        role: true,
        avatar: true
      }
    });

    if (!user) {
      throw new AuthenticationError('用户不存在');
    }

    // 生成新的令牌
    const newToken = jwt.sign(
      { userId: user.id, role: user.role },
      config.JWT_SECRET,
      { expiresIn: config.JWT_ACCESS_EXPIRES_IN } as any
    );

    res.json({
      code: 200,
      message: '令牌刷新成功',
      data: {
        user,
        token: newToken
      }
    });
  } catch (error) {
    next(error);
  }
});

// 获取当前用户信息
router.get('/me', async (req, res, next) => {
  try {
    const token = req.headers.authorization?.replace('Bearer ', '');

    if (!token) {
      throw new AuthenticationError('令牌不能为空');
    }

    // 验证令牌
    const decoded = jwt.verify(token, config.JWT_SECRET) as any;
    
    // 查找用户
    const user = await prisma.user.findUnique({
      where: { id: decoded.userId },
      select: {
        id: true,
        username: true,
        email: true,
        role: true,
        avatar: true,
        status: true,
        createdAt: true,
        lastLoginAt: true,
        updatedAt: true,
        fullName: true,
        phone: true,
        department: true,
        position: true,
        bio: true,
        location: true,
        website: true,
        skills: true
      }
    });

    if (!user) {
      throw new AuthenticationError('用户不存在');
    }

    res.json({
      code: 200,
      message: '获取用户信息成功',
      data: { user }
    });
  } catch (error) {
    next(error);
  }
});

// 退出登录
router.post('/logout', (req, res) => {
  res.json({
    code: 200,
    message: '退出登录成功',
    data: null
  });
});

// 更新用户资料
router.put('/profile', [
  body('username').optional().isLength({ min: 3, max: 50 }).withMessage('用户名长度必须在3-50个字符之间'),
  body('email').optional().isEmail().withMessage('请输入有效的邮箱地址'),
  body('fullName').optional().isLength({ max: 100 }).withMessage('姓名长度不能超过100个字符'),
  body('phone').optional().isLength({ max: 20 }).withMessage('手机号长度不能超过20个字符'),
  body('department').optional().isLength({ max: 100 }).withMessage('部门名称长度不能超过100个字符'),
  body('position').optional().isLength({ max: 100 }).withMessage('职位名称长度不能超过100个字符'),
  body('bio').optional().isLength({ max: 500 }).withMessage('个人简介长度不能超过500个字符'),
  body('location').optional().isLength({ max: 100 }).withMessage('地区名称长度不能超过100个字符'),
  body('website').optional().isLength({ max: 200 }).withMessage('网站地址长度不能超过200个字符'),
  body('skills').optional().isArray().withMessage('技能标签必须是数组格式')
], async (req, res, next) => {
  try {
    // 验证请求参数
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      const errorMessages = errors.array().map(err => `${err.type === 'field' ? err.path : 'unknown'}: ${err.msg}`).join(', ');
      throw new CustomError(`请求参数验证失败: ${errorMessages}`, 400);
    }

    const token = req.headers.authorization?.replace('Bearer ', '');
    if (!token) {
      throw new AuthenticationError('令牌不能为空');
    }

    // 验证令牌
    const decoded = jwt.verify(token, config.JWT_SECRET) as any;
    
    // 查找用户
    const existingUser = await prisma.user.findUnique({
      where: { id: decoded.userId }
    });

    if (!existingUser) {
      throw new AuthenticationError('用户不存在');
    }

    // 准备更新数据
    const updateData: any = {};
    
    // 基础字段
    if (req.body.username !== undefined) updateData.username = req.body.username;
    if (req.body.email !== undefined) updateData.email = req.body.email;
    
    // 扩展字段
    if (req.body.fullName !== undefined) updateData.fullName = req.body.fullName;
    if (req.body.phone !== undefined) updateData.phone = req.body.phone;
    if (req.body.department !== undefined) updateData.department = req.body.department;
    if (req.body.position !== undefined) updateData.position = req.body.position;
    if (req.body.bio !== undefined) updateData.bio = req.body.bio;
    if (req.body.location !== undefined) updateData.location = req.body.location;
    if (req.body.website !== undefined) updateData.website = req.body.website;
    if (req.body.skills !== undefined) updateData.skills = req.body.skills;

    // 更新用户信息
    const updatedUser = await prisma.user.update({
      where: { id: decoded.userId },
      data: updateData,
      select: {
        id: true,
        username: true,
        email: true,
        role: true,
        avatar: true,
        status: true,
        fullName: true,
        phone: true,
        department: true,
        position: true,
        bio: true,
        location: true,
        website: true,
        skills: true,
        createdAt: true,
        lastLoginAt: true
      }
    });

    res.json({
      code: 200,
      message: '用户资料更新成功',
      data: updatedUser
    });
  } catch (error) {
    next(error);
  }
});

// 上传用户头像
router.post('/avatar', upload.single('avatar'), async (req, res, next) => {
  try {
    const token = req.headers.authorization?.replace('Bearer ', '');
    if (!token) {
      throw new AuthenticationError('令牌不能为空');
    }

    if (!req.file) {
      throw new CustomError('请选择要上传的头像文件', 400);
    }

    // 验证令牌
    const decoded = jwt.verify(token, config.JWT_SECRET) as any;
    
    // 查找用户
    const existingUser = await prisma.user.findUnique({
      where: { id: decoded.userId }
    });

    if (!existingUser) {
      throw new AuthenticationError('用户不存在');
    }

    // 生成头像URL
    const avatarUrl = `/uploads/avatars/${req.file.filename}`;
    
    // 删除旧头像文件（如果存在）
    if (existingUser.avatar && existingUser.avatar.startsWith('/uploads/avatars/')) {
      const oldAvatarPath = path.join(__dirname, '../../', existingUser.avatar);
      if (fs.existsSync(oldAvatarPath)) {
        fs.unlinkSync(oldAvatarPath);
      }
    }

    // 更新用户头像
    const updatedUser = await prisma.user.update({
      where: { id: decoded.userId },
      data: { avatar: avatarUrl },
      select: {
        id: true,
        username: true,
        email: true,
        role: true,
        avatar: true,
        status: true
      }
    });

    res.json({
      code: 200,
      message: '头像上传成功',
      data: { avatar: avatarUrl }
    });
  } catch (error) {
    next(error);
  }
});

// 心跳检测接口
router.post('/heartbeat', async (req, res, next) => {
  try {
    const token = req.headers.authorization?.replace('Bearer ', '');
    if (!token) {
      throw new AuthenticationError('令牌不能为空');
    }

    // 验证令牌
    const decoded = jwt.verify(token, config.JWT_SECRET) as any;
    
    // 查找用户
    const existingUser = await prisma.user.findUnique({
      where: { id: decoded.userId }
    });

    if (!existingUser) {
      throw new AuthenticationError('用户不存在');
    }

    // 更新用户最后活动时间（暂时注释掉，等Prisma客户端更新后再启用）
    // await prisma.user.update({
    //   where: { id: decoded.userId },
    //   data: { 
    //     lastActivityAt: new Date()
    //   }
    // });

    // 暂时返回成功，等数据库迁移完成后再实现完整的会话管理
    res.json({
      code: 200,
      message: '心跳检测成功',
      data: {
        timestamp: new Date().toISOString(),
        userId: decoded.userId
      }
    });
  } catch (error) {
    next(error);
  }
});

// 清理接口（用户登出或标签页关闭）
router.post('/cleanup', async (req, res, next) => {
  try {
    const token = req.headers.authorization?.replace('Bearer ', '');
    if (!token) {
      throw new AuthenticationError('令牌不能为空');
    }

    // 验证令牌
    const decoded = jwt.verify(token, config.JWT_SECRET) as any;
    
    // 查找用户
    const existingUser = await prisma.user.findUnique({
      where: { id: decoded.userId }
    });

    if (!existingUser) {
      throw new AuthenticationError('用户不存在');
    }

    // 暂时返回成功，等数据库迁移完成后再实现完整的会话管理
    res.json({
      code: 200,
      message: '清理成功',
      data: {
        timestamp: new Date().toISOString(),
        userId: decoded.userId
      }
    });
  } catch (error) {
    next(error);
  }
});

export { router as authRoutes };
